#include <lib3d/node/Node2D.h>

namespace liba {
namespace lib3d {
namespace node {

Node2D::Node2D( const Atom & name, Node * parent )
	: Node(name, parent)
{ }

Node2D::Node2D(const Node2D& rhs)
	: Node(rhs)
{ }

math::Rect<float> Node2D::GetGlobalBounds()
{
	math::Rect<float> local = this->GetLocalBounds();
	math::Rect<float> result = 
		math::Transform(local, this->GetPosition().z, this->GetGlobalMatrix());

	return result;
}

float Node2D::GetZ()
{
	return this->GetPosition().z;
}

math::Vector2<float> Node2D::GlobalToLocal(const math::Vector2<float>& pt)
{
	lib3d::Vector globalVector(pt.x, pt.y, this->GetGlobalPosition().z);
	// Following can be easily optimized by caching inverted matrix
	lib3d::Vector localVector = lib3d::Matrix::invert(this->GetGlobalMatrix()) * globalVector;
	return math::Vector2<float>(localVector.x, localVector.y);
}

math::Vector2<float> Node2D::LocalToGlobal(const math::Vector2<float>& pt)
{
	lib3d::Vector localVector(pt.x, pt.y, this->GetPosition().z);
	lib3d::Vector globalVector = this->GetGlobalMatrix() * localVector;
	return math::Vector2<float>(globalVector.x, globalVector.y);
}

void Node2D::OnGlobalMatrixInvalidated()
{
	Node::OnGlobalMatrixInvalidated();
	this->FireBoundsChanged();
}

} // namespace node
} // namespace lib3d
} // namespace liba
